mod proto;

use proto::hello::say_server::*;
use tonic::{Status, Response, Request, transport::Server, Code, Interceptor};
use crate::proto::hello::{HelloResponse, HelloRequest};

#[tokio::main]
async fn main()-> Result<(), Box<dyn std::error::Error>> {
    let say = HelloServer{};
    let say = SayServer::with_interceptor(say,Interceptor::new(oauth_check));
    Server::builder()
        .concurrency_limit_per_connection(128)
        .timeout(std::time::Duration::from_secs(3))
        .add_service(say)
        .serve("[::1]:666".parse().unwrap())
        .await?;
    Ok(())
}

pub struct HelloServer{
}

//回调函数，执行注册方法
#[tonic::async_trait]
impl Say for HelloServer{
    async fn say_hello(&self, request: Request<HelloRequest>) -> Result<Response<HelloResponse>, Status> {
        wd_log::log_info_ln!("client request:{}",request.get_ref().value);
        let resp = Response::new(
            HelloResponse{value:String::from("hi,i am server")}
        );
        Ok(resp)
    }
}

//鉴权检查，打印请求id
fn oauth_check(reqs: Request<()>) -> Result<Request<()>, Status>  {
    let reqs = match reqs.metadata().get("authorization") {
        Some(s)=>{
            let token = s.to_str().unwrap();
            wd_log::log_info_ln!("token:{}",token);
            reqs
        }
        None=>{return Err(Status::new(Code::PermissionDenied,"token is null"))}
    };
    match reqs.metadata().get("request_id") {
        Some(s)=>{
            let rid = s.to_str().unwrap();
            wd_log::log_info_ln!("request_id:{}",rid);
            Ok(reqs)
        }
        None=> Err(Status::new(Code::DataLoss,"request_id in null"))
    }
}